home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacWT 0.9 / wt Mac Source / Networking.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-10  |  10.3 KB  |  375 lines  |  [TEXT/CWIE]

  1. /*
  2. ** File:        Networking.c
  3. **
  4. ** Written by:    Bill Hayden
  5. **                Nikol Software
  6. **
  7. ** Based on:    AppleTalk.c and AEUtils.c
  8. **                by Pete Helme, Jim Luther, and Eric Soldan of Apple Computer, Inc.
  9. **
  10. ** Copyright © 1995 Nikol Software
  11. ** All rights reserved.
  12. **
  13. */
  14.  
  15.  
  16.  
  17.  
  18. /*****************************************************************************/
  19.  
  20.  
  21.  
  22.  
  23. #ifndef __ERRORS__
  24. #include <Errors.h>
  25. #endif
  26.  
  27. #ifndef __OSUTILS__
  28. #include <OSUtils.h>
  29. #endif
  30.  
  31. #ifndef __RESOURCES__
  32. #include <Resources.h>
  33. #endif
  34.  
  35. #include "StringUtils.h"
  36. #include "Networking.h"
  37.  
  38.  
  39. #define        kATPTimeOutVal            3            /* re-try ATP SendRequest every 3 seconds */
  40. #define        kATPRetryCount            5            /* for five times */
  41. #define        kZonesSize                578            /* size of buffer for zone names */
  42. #define        kGetMyZoneCall            0x07000000    /* GetMyZone indicator */
  43. #define        kGetZoneListCall        0x08000000    /* GetZoneList indicator */
  44. #define        kZIPSocket                6            /* the Zone Information Protocol socket */
  45. #define        kMoreZones                0xFF000000     /* mask to see if more zones to come */
  46. #define        kZoneCount                0x0000FFFF     /* mask to count zones in buffer */
  47.  
  48. #define        kTupleSize    104
  49. #define        kMaxTuples    1
  50.  
  51.  
  52.  
  53. /*****************************************************************************/
  54.  
  55.  
  56.  
  57.  
  58.  
  59. /* Create the list of zones on the network.  Find a bridge to talk to, if one is
  60. ** present, then ask it for zone names.  Add the names to the passed-in list. */
  61.  
  62. OSErr    DoBuildZoneList(ListHandle listHndl)
  63. {
  64. #if 0
  65.     ATPParamBlock    atppb;
  66.     char            zones[kZonesSize], *zptr, data[255];
  67.     OSErr            err;
  68.  
  69.     BDSElement    dBDS;                /* the BDS for GetZoneList call */
  70.     short        index, count, i;
  71.     short        ignore;
  72.     short        nodeNetAddress, bridgeNode;
  73.  
  74.     dBDS.buffSize = kZonesSize;                                    /* set up BDS */
  75.     dBDS.buffPtr = zones;
  76.  
  77.     atppb.ATPatpFlags = 0;
  78.  
  79.     /* Get network address of node & node ID of bridge (if any). */
  80.  
  81.     err = GetNodeAddress(&ignore, &nodeNetAddress);
  82.     if (err) return(err);
  83.  
  84.     if (!(bridgeNode = GetBridgeAddress())) return(noErr);
  85.         /* We have added all zero zones to the list, so we are done. */
  86.  
  87.     atppb.ATPaddrBlock.aNet = nodeNetAddress;
  88.     atppb.ATPaddrBlock.aNode = bridgeNode;            /* Get node of bridge. */
  89.     atppb.ATPaddrBlock.aSocket = kZIPSocket;        /* The socket we want. */
  90.     atppb.ATPreqLength = 0;
  91.     atppb.ATPreqPointer = nil;
  92.     atppb.ATPbdsPointer = (Ptr) &dBDS;
  93.     atppb.ATPnumOfBuffs = 1;
  94.     atppb.ATPtimeOutVal = kATPTimeOutVal;
  95.     atppb.ATPretryCount = kATPRetryCount;
  96.  
  97.     index = 1;
  98.     count = 0;
  99.  
  100.     do {
  101.         atppb.ATPuserData = kGetZoneListCall + index;    /* Indicate GetZoneList request. */
  102.         err = PSendRequest(&atppb, false);                /* Send sync request. */
  103.         if (err) return(err);
  104.  
  105.         count += dBDS.userBytes & kZoneCount;            /* find out how many returned */
  106.         zptr = zones;                                    /* put current pointer at start */
  107.         do {                                            /* get each zone */
  108.             for (i = zptr[0]; i; --i)
  109.                 data[i - 1] = zptr[i];
  110.             CLInsert(listHndl, data, zptr[0], -1, 0);
  111.             zptr += (*zptr + 1 );                        /* bump up current pointer*/
  112.             ++index;                                    /* increment which zone */
  113.         } while(index <= count);
  114.  
  115.     } while ((dBDS.userBytes & kMoreZones) == 0);        /*     keep going until none left */
  116.  
  117. #endif
  118.     return(noErr);
  119. }
  120.  
  121.  
  122.  
  123. /*****************************************************************************/
  124.  
  125.  
  126.  
  127. /* Select our zone in the zone list. */
  128.  
  129. OSErr    OldStyleGetMyZone(StringPtr str);
  130. OSErr    HiliteUserZone(ListHandle listHndl)
  131. {
  132.     Str32            zone;
  133.     short            zoneLen, i;
  134.     Point            cell;
  135.     OSErr            err;
  136.  
  137.     if (!(err = OldStyleGetMyZone(zone)))
  138.         {
  139.         for (zoneLen = zone[i = 0]; i < zoneLen; ++i) zone[i] = zone[i + 1];
  140.         cell.h = cell.v = 0;
  141.         if (LSearch(zone, zoneLen, nil, &cell, listHndl))
  142.             {
  143.             LSetSelect(true, cell, listHndl);
  144.             LAutoScroll(listHndl);
  145.             }
  146.         }
  147.     return(err);
  148. }
  149.  
  150.  
  151.  
  152. /*****************************************************************************/
  153.  
  154.  
  155.  
  156. OSErr    OldStyleGetMyZone(StringPtr str)
  157. {
  158.     ATPParamBlock    atppb;
  159.     OSErr            err;
  160.  
  161.     BDSElement    dBDS;                /* the BDS for GetZoneList call */
  162.     short        ignore;
  163.     short        nodeNetAddress, bridgeNode;
  164.  
  165.     dBDS.buffSize = sizeof(Str32);
  166.     dBDS.buffPtr  = (Ptr)str;
  167.  
  168.     atppb.ATPatpFlags = 0;
  169.  
  170.         /* Get network address of node & node ID of bridge (if any). */
  171.  
  172.     err = GetNodeAddress(&ignore, &nodeNetAddress);
  173.     if (err) return(err);
  174.  
  175.     if (!(bridgeNode = GetBridgeAddress())) return(noErr);
  176.         /* We have added all zero zones to the ist, so we are done. */
  177.  
  178.     atppb.ATPaddrBlock.aNet    = nodeNetAddress;
  179.     atppb.ATPaddrBlock.aNode   = bridgeNode;            /* Get node of bridge. */
  180.     atppb.ATPaddrBlock.aSocket = kZIPSocket;            /* The socket we want. */
  181.     atppb.ATPreqLength  = 0;
  182.     atppb.ATPreqPointer = nil;
  183.     atppb.ATPbdsPointer = (Ptr) &dBDS;
  184.     atppb.ATPnumOfBuffs = 1;
  185.     atppb.ATPtimeOutVal = kATPTimeOutVal;
  186.     atppb.ATPretryCount = kATPRetryCount;
  187.  
  188.     atppb.ATPuserData = kGetMyZoneCall;                /* Indicate GetMyZone request. */
  189.     return(PSendRequest(&atppb, false));            /* Send sync request. */
  190. }
  191.  
  192.  
  193.  
  194.  
  195. /*****************************************************************************/
  196.  
  197.  
  198.  
  199. /* This routine finds the socket used by the PPC Toolbox (it's the one with
  200. ** type 'PPCToolBox') and gives it a NBP alias (it registers a new NBP name
  201. ** on that socket) with the type passed in newNBPType.  The NameTableEntry
  202. ** record passed to this routine must be allocated globally (or must be a
  203. ** locked block on the heap until RemoveNBPAlias is called).  The variable
  204. ** newEntity is filled in with the new entity name and is returned to the
  205. ** function's caller so it can be passed to the RemoveNBPAlias function
  206. ** (below).  You'll get an error if any call fails, if an entity of type
  207. ** 'PPCToolBox' is not found (usually because either Program Linking isn't
  208. ** enabled or AppleTalk is disabled), or if RegisterName fails because >100
  209. ** copies of your application are running on the one machine (yea, right). */
  210.  
  211. OSErr    AddPPCNBPAlias(NamesTableEntry *theNTE, Str32 newNBPType, EntityName *newEntity)
  212. {
  213.     OSErr            err;
  214.     MPPParamBlock    pb;
  215.     char            keepSelfFlag;
  216.     short            keepResFile, origLen, num, len;
  217.  
  218.     EntityName        myEntityName;
  219.  
  220.     AddrBlock        myAddrBlock;
  221.     char            myRetBuff[kTupleSize];
  222.     Handle            machineNameHndl;
  223.     Str32            machineName;
  224.  
  225.     pb.SETSELF.newSelfFlag = 1;
  226.     err = PSetSelfSend(&pb, false);                        /* Turn on self-send. */
  227.     if (err) return(err);
  228.  
  229.     keepSelfFlag = pb.SETSELF.oldSelfFlag;                /* Keep old self-send flag. */
  230.  
  231.     keepResFile = CurResFile();
  232.     UseResFile(0);
  233.     machineNameHndl = GetResource('STR ', -16413);        /* Get machine name. */
  234.     UseResFile(keepResFile);
  235.  
  236.     if (!machineNameHndl)
  237.         {
  238.         pb.SETSELF.newSelfFlag = keepSelfFlag;
  239.         PSetSelfSend(&pb, false);
  240.         return(ResError());
  241.         }
  242.  
  243.     pcpy(machineName, (StringPtr)*machineNameHndl);        /* Keep a copy of the machine name.   */
  244.     ReleaseResource(machineNameHndl);                    /* Release the machine name resource. */
  245.  
  246.     NBPSetEntity((Ptr)&myEntityName, (StringPtr)machineName, (StringPtr)"\pPPCToolBox", (StringPtr)"\p*");
  247.  
  248.     pb.NBPinterval    = 1;                    /* We want to build the entity name using */
  249.     pb.NBPcount       = 1;                    /* the machine name and 'PPCToolBox'.     */
  250.     pb.NBPentityPtr   = (Ptr)&myEntityName;
  251.     pb.NBPretBuffPtr  = myRetBuff;
  252.     pb.NBPretBuffSize = (kTupleSize * kMaxTuples);
  253.     pb.NBPmaxToGet    = kMaxTuples;
  254.  
  255.     if (!(err = PLookupName(&pb, false)))
  256.         {                            /* If lookup was okay... */
  257.         if (pb.NBPnumGotten)
  258.             {                        /* If entity was found... */
  259.                                     /* ...we found the socket used by the PPC Toolbox. */
  260.                                     /* This means that there is a socket, due to program */
  261.                                     /* linking being turned on. */
  262.  
  263.             NBPExtract(myRetBuff, pb.NBPnumGotten, 1, &myEntityName, &myAddrBlock);
  264.                 /* Break the tuple into component parts. */
  265.  
  266.             for (origLen = machineName[num = 0]; num < 100;)
  267.                 {
  268.                 pb.NBPinterval   = 7;
  269.                 pb.NBPcount      = 5;
  270.                 pb.NBPentityPtr  = (Ptr)theNTE;
  271.                 pb.NBPverifyFlag = 1;
  272.  
  273.                 NBPSetNTE((Ptr)theNTE, (StringPtr)machineName, (StringPtr)newNBPType, (StringPtr)"\p*", myAddrBlock.aSocket);
  274.                 NBPSetEntity((Ptr)newEntity, (StringPtr)machineName,(StringPtr) newNBPType, (StringPtr)"\p*");
  275.                 err = PRegisterName(&pb, false);
  276.  
  277.                 if (err != nbpDuplicate) break;
  278.                     /* We registered the name, (or badness happened), so we are done. */
  279.  
  280.                 len = 31;        /* The name we tried already exists, so make up an alternate. */
  281.                 if (++num > 9)
  282.                     --len;
  283.                 if (origLen > len)
  284.                     origLen = len;
  285.                 machineName[0] = origLen;
  286.                 pcatdec(machineName, num);
  287.                 }
  288.             }
  289.         }
  290.  
  291.     pb.SETSELF.newSelfFlag = keepSelfFlag;
  292.     PSetSelfSend(&pb, false);
  293.  
  294.     return(err);
  295. }
  296.  
  297.  
  298.  
  299.  
  300. /*****************************************************************************/
  301.  
  302.  
  303.  
  304. /* This function removes the entity specified by theEntity from the registered
  305. ** names queue.  You'll get an error if theEntity hasn't been registered on
  306. ** this Macintosh with RegisterName. */
  307.  
  308. OSErr    RemoveNBPAlias(EntityPtr theEntity)
  309. {
  310.     MPPParamBlock    pb;
  311.  
  312.     pb.MPPioCompletion = nil;
  313.     pb.NBPentityPtr    = (Ptr)theEntity;
  314.     return(PRemoveName(&pb, false));
  315. }
  316.  
  317.  
  318.  
  319.  
  320. /*****************************************************************************/
  321.  
  322.  
  323.  
  324.  
  325. OSErr    MakeTarget(AEAddressDesc *target, short replyMode,
  326.                    Str255 prompt, Str255 applListLabel,
  327.                    PPCFilterUPP portFilter, char *theLocNBPType)
  328. {
  329.     OSErr                    err;
  330.     TargetID                theTargetID;
  331.  
  332.     static LocationNameRec    location;
  333.     static PortInfoRec        portInfo;
  334.     static Boolean            defaultOK = false;
  335.  
  336.  
  337.     target->dataHandle = nil;
  338.         /* Assume we will fail and nil this descriptor out. */
  339.  
  340.     err = PPCBrowser(    prompt,            /* Browse dialog box prompt.           */
  341.                         applListLabel,    /* The 'programs' list title.           */
  342.                         defaultOK,        /* Initially false.                       */
  343.                         &location,        /* Correct if defaultOK is true.       */
  344.                         &portInfo,        /* Correct if defaultOK is true.       */
  345.                         portFilter,        /* Port filtering.                       */
  346.                         (StringPtr)theLocNBPType    /* List ports of this type */
  347.                     );
  348.  
  349.     if (!err)
  350.         {
  351.         defaultOK = true;
  352.         
  353.         theTargetID.location = location;
  354.         theTargetID.name     = portInfo.name;
  355.                 /* The fields sessionID does not need to be filled in now.
  356.                 ** The sessionID is returned when you actually connect to
  357.                 ** a port.  You can then use the sessionID from that point
  358.                 ** on to improve speed.
  359.                 **
  360.                 ** You also don't need to fill in the recvrName field at this
  361.                 ** point.  This is filled in, again, when the session is
  362.                 ** actually established.
  363.                 **
  364.                 ** We need the whole dealie for our target, since
  365.                 ** it is out on the net somewhere. */
  366.  
  367.         err = AECreateDesc(    typeTargetID,            /* Standard target descriptor type. */
  368.                             (Ptr)&theTargetID,        /* The data for the descriptor.        */
  369.                             sizeof(theTargetID),    /* Size of the data.                */
  370.                             target );                /* Wherefore art thou desc.            */
  371.         }
  372.  
  373.     return (err);
  374. }
  375.